package cn.haoran.modules.sys.service.impl;

import cn.haoran.common.exception.AppException;
import cn.haoran.common.utils.Constant;
import cn.haoran.common.utils.PageUtils;
import cn.haoran.common.utils.Query;
import cn.haoran.modules.app.entity.UserEntity;
import cn.haoran.modules.sys.dao.SysUserDao;
import cn.haoran.modules.sys.entity.SysRoleEntity;
import cn.haoran.modules.sys.entity.SysUserEntity;
import cn.haoran.modules.sys.entity.SysUserTokenEntity;
import cn.haoran.modules.sys.service.SysRoleService;
import cn.haoran.modules.sys.service.SysUserRoleService;
import cn.haoran.modules.sys.service.SysUserService;
import cn.haoran.modules.sys.service.SysUserTokenService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 系统用户
 *
 * Create by hanran on 2019/6/15
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserTokenService tokenService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String username = (String)params.get("username");
        Long createUserId = (Long)params.get("createUserId");

        Page<SysUserEntity> page = this.selectPage(
                new Query<SysUserEntity>(params).getPage(),
                new EntityWrapper<SysUserEntity>()
                        .like(StringUtils.isNotBlank(username),"username", username)
                        .eq(createUserId != null,"create_user_id", createUserId)
        );

        return new PageUtils(page);
    }

    @Override
    public List<String> queryAllPerms(Long userId) {
        return baseMapper.queryAllPerms(userId);
    }

    @Override
    public List<Long> queryAllMenuId(Long userId) {
        return baseMapper.queryAllMenuId(userId);
    }

    @Override
    public SysUserEntity queryByUserName(String username) {
        return baseMapper.queryByUserName(username);
    }

    @Override
    public SysUserEntity queryInfo(Long id) {
        List<String> roleNames = new ArrayList<>();
        SysUserEntity user = this.selectById(id);
        List<Long> roleIdList = sysUserRoleService.queryRoleIdList(id);
        if(roleIdList != null && roleIdList.size() > 0) {
            // 获取roleName
            List<SysRoleEntity> roles = sysRoleService.selectBatchIds(roleIdList);
            if(roles != null) {
                for(SysRoleEntity role : roles) {
                    roleNames.add(role.getRoleName());
                }
            }
        } else {
            if("admin".equals(user.getUsername())) {
                roleNames.add("超级管理员");
            }
        }
        // 获取最后登陆时间
        SysUserTokenEntity tokenEntity = tokenService.selectById(id);
        if(tokenEntity != null) {
            user.setLastLoginTime(tokenEntity.getUpdateTime());
        }
        user.setRoleNameList(roleNames);
        user.setPassword("");
        user.setSalt("");
        return user;
    }

    @Override
    @Transactional
    public void save(SysUserEntity user) {
        user.setCreateTime(new Date());
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
        user.setSalt(salt);
        this.insert(user);

        //检查角色是否越权
        checkRole(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional
    public void update(SysUserEntity user) {
        if(StringUtils.isBlank(user.getPassword())){
            user.setPassword(null);
        }else{
            user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
        }
        this.updateById(user);

        //检查角色是否越权
        checkRole(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    public void deleteBatch(Long[] userId) {
        this.deleteBatchIds(Arrays.asList(userId));
        //删除角色与用户关联
        sysUserRoleService.deleteBatchByUserIds(userId);
    }

    @Override
    public boolean updatePassword(Long userId, String password, String newPassword) {
        SysUserEntity userEntity = new SysUserEntity();
        userEntity.setPassword(newPassword);
        return this.update(userEntity,
                new EntityWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
    }

    /**
     * 检查角色是否越权
     */
    private void checkRole(SysUserEntity user){
        if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
            return;
        }
        //如果不是超级管理员，则需要判断用户的角色是否自己创建
        if(user.getCreateUserId() == Constant.SUPER_ADMIN){
            return ;
        }

        //查询用户创建的角色列表
        List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

        //判断是否越权
        if(!roleIdList.containsAll(user.getRoleIdList())){
            throw new AppException("新增用户所选角色，不是本人创建");
        }
    }
}
